package shiyan2;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;


public class TCPServer {
    public static void main(String[] args) {
        // 服务端监听的端口号
        final int PORT = 8080;
        System.out.println("[Server] 启动中，监听端口 " + PORT + "···");

        // 使用try-with-resources创建ServerSocket，自动关闭资源
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            // 循环监听客户端连接（服务端持续运行）
            while (true) {
                // 阻塞等待客户端连接，连接成功后返回Socket对象
                Socket socket = serverSocket.accept();
                System.out.println("[Server]客户端已连接" + socket.getInetAddress());

                // 为每个客户端连接创建新线程处理，避免单线程阻塞
                new Thread(new ClientHandler(socket)).start();
            }
        } catch (IOException e) {
            throw new RuntimeException("[Server] 启动或监听异常：" + e.getMessage());
        }
    }


    private static class ClientHandler implements Runnable {
        // 与客户端通信的Socket对象
        private final Socket socket;

        // 构造方法，初始化客户端Socket
        ClientHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            // 使用try-with-resources创建输入输出流，自动关闭资源
            try (// 从Socket获取输入流，用于读取客户端发送的数据（指定UTF-8编码）
                 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
                 // 从Socket获取输出流，用于向客户端发送数据（指定UTF-8编码）
                 BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8))
            ) {
                String line;
                // 循环读取客户端发送的一行数据（readLine()阻塞等待，直到收到换行符）
                while ((line = in.readLine()) != null) {
                    System.out.println("[Server] 收到：" + line + "  来自 " + socket.getRemoteSocketAddress());

                    // 构造响应数据
                    String resp = line + "已收到";
                    // 发送响应给客户端（需添加换行符，否则客户端readLine()会阻塞等待）
                    out.write(resp);
                    out.write("\r\n");
                    out.flush(); // 强制刷新缓冲区，确保数据立即发送

                    // 判断客户端是否发送"exit"，若则断开连接
                    if ("exit".equalsIgnoreCase(line.trim())) {
                        break;
                    }
                }

            } catch (IOException e) {
                throw new RuntimeException("[Server] 与客户端" + socket.getRemoteSocketAddress() + "通信异常：" + e.getMessage());
            } finally {
                // 无论是否发生异常，最终关闭Socket连接
                try {
                    socket.close();
                } catch (IOException ignore) {
                    // 关闭异常可忽略
                }
                System.out.println("[Server] 连接关闭：" + socket.getRemoteSocketAddress());
            }
        }
    }
}